package com.wendy.controller;

import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.ExcelImportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.afterturn.easypoi.excel.entity.ImportParams;
import cn.afterturn.easypoi.excel.entity.enmus.ExcelType;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.tree.Tree;
import cn.hutool.core.lang.tree.TreeNode;
import cn.hutool.core.lang.tree.TreeUtil;
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.util.URLUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.wendy.entity.RegionList;
import com.wendy.service.IRegionListService;
import com.wendy.vo.R;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.Cleanup;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 行政区划代码表 前端控制器
 * </p>
 *
 * @author wendy
 * @since 2021-12-30
 */
@Slf4j
@RestController
@RequiredArgsConstructor
@Api(tags = "行政区划代码表")
@RequestMapping("/region")
public class RegionListController {

  public final IRegionListService regionListService;

  /**
   * hu-tool 实现
   * @param code 省级行政区划代码
   * @return Tree
   */
  @GetMapping("/treeNodeList")
  @ApiOperation(value = "查询树状节点列表")
  public R<List<Tree<String>>> treeNodeList(@RequestParam(value = "code", required = false)
                                      @ApiParam(name = "省级行政区划代码") String code) {
    QueryWrapper<RegionList> query = Wrappers.query();
    if(null != code){
      query.eq("province_code", code);
    }
    List<RegionList> all = regionListService.list(query);
    List<TreeNode<String>> nodeList = CollUtil.newArrayList();
    all.forEach(r -> {
      TreeNode<String> treeNode =
              new TreeNode<>(r.getAreaCode(), r.getParentCode(), r.getAreaName(), r.getAreaCode());
      // 扩展属性
      Map<String, Object> extra = new HashMap<>();
      extra.put("areaLevel", r.getAreaLevel());
      extra.put("isEnable", r.getIsEnable());
      treeNode.setExtra(extra);
      nodeList.add(treeNode);
    });
    return R.ok(TreeUtil.build(nodeList, "-1"));
  }

  @GetMapping("/treeList")
  @ApiOperation(value = "查询树状列表")
  public R<List<RegionList>> treeList(@RequestParam(value = "code", required = false)
                              @ApiParam(name = "省级行政区划代码") String code) {
    QueryWrapper<RegionList> query = Wrappers.query();
    if(null != code){
      query.eq("province_code", code);
    }
    //拿到菜单的所有数据
    List<RegionList> regions = regionListService.list(query);
    //存储根节点的菜单，即一级菜单
    List<RegionList> rootList = new ArrayList<>();
    //遍历所有数据，找到根节点菜单
    for (RegionList region : regions) {
      if ("-1".equals(region.getParentCode())) {
        //找到根节点菜单的时候，寻找这个根节点菜单下的子节点菜单。
        findChildren(region, regions);
        //添加到根节点的列表中
        rootList.add(region);
      }
    }

    return R.ok(rootList);
  }

  private void findChildren(RegionList root, List<RegionList> list) {
    List<RegionList> children = new ArrayList<>();
    //遍历所有数据，找到是入参父节点的子节点的数据，然后加到children集合中。
    for (RegionList region : list) {
      if (root.getAreaCode().equals(region.getParentCode())) {
        children.add(region);
      }
    }
    //若子节点不存在，那么就不必再遍历子节点中的子节点了 直接返回。
    if (children.isEmpty()) {
      return;
    }
    //设置父节点的子节点列表
    root.setChildren(children);
    //若子节点存在，接着递归调用该方法，寻找子节点的子节点。
    for (RegionList child : children) {
      findChildren(child, list);
    }
  }

  @GetMapping("/pageList")
  @ApiOperation(value = "分页查询列表")
  public R<IPage<RegionList>> pageList(@RequestParam(value = "pageNum", defaultValue = "1") Long pageNum,
                            @RequestParam(value = "pageSize", defaultValue = "10") Long pageSize) {

    IPage<RegionList> page = regionListService.page(new Page<>(pageNum, pageSize), null);
    return R.ok(page, "查询成功");
  }

  @PostMapping("/get")
  @ApiOperation(value = "条件查询")
  public R<List<RegionList>> list(@RequestBody RegionList regionList) {
    List<RegionList> regionListList = regionListService.list(new QueryWrapper<>(regionList));
    return R.ok(regionListList, "查询成功");
  }

  @GetMapping("/get/{id}")
  @ApiOperation(value = "根据id查详情")
  public R<RegionList> get(@PathVariable("id") String id) {
    RegionList regionList = regionListService.getById(id);
    return R.ok(regionList, "查询成功");
  }

  @PostMapping("/save")
  @ApiOperation(value = "新增")
  public R<String> save(@RequestBody RegionList regionList) {
    regionListService.save(regionList);
    return R.ok("保存成功");
  }

  @PostMapping("/delete/{id}")
  @ApiOperation(value = "根据id删除")
  public R<String> delete(@PathVariable("id") Long id) {
    regionListService.removeById(id);
    return R.ok("删除成功");
  }

  @PostMapping("/update")
  @ApiOperation(value = "根据id修改")
  public R<String> update(@RequestBody RegionList regionList) {
    regionListService.updateById(regionList);
    return R.ok("更新成功");
  }

  @SneakyThrows
  @PostMapping("/import")
  @ApiOperation(value = "数据导入")
  public R<List<RegionList>> importExcel(@RequestParam MultipartFile file) {
    ImportParams params = new ImportParams();
    params.setTitleRows(1);
    @Cleanup InputStream inputStream = file.getInputStream();
    List<RegionList> excelList = ExcelImportUtil.importExcel(inputStream, RegionList.class, params);
    regionListService.saveOrUpdateBatch(excelList);
    return R.ok(excelList);
  }

  @SneakyThrows
  @GetMapping("/export")
  @ApiOperation("数据导出")
  public void export(HttpServletResponse response) {
    List<RegionList> list = regionListService.list();
    ExportParams exportParams = new ExportParams();
    exportParams.setType(ExcelType.XSSF);
    exportParams.setTitle("行政区划代码表");
    exportParams.setSheetName("全国");
    Workbook sheets = ExcelExportUtil.exportExcel(exportParams, RegionList.class, list);
    ServletOutputStream output = response.getOutputStream();
    response.setHeader("Content-Disposition", "attachment;filename=" + URLUtil.encode("行政区划代码表.xlsx", CharsetUtil.CHARSET_UTF_8));
    response.setContentType("application/octet-stream");
    response.setCharacterEncoding("UTF-8");
    sheets.write(output);
  }

}
